﻿/*
 * System.h
 *
 */
#ifndef __GDK_SYSTEM_H__
#define __GDK_SYSTEM_H__

#include <gdk/core/Types.h>
#include <gdk/core/Unknown.h>
#include <gdk/core/Mutex.h>
#include <gdk/core/String.h>
#include <gdk/core/Semaphore.h>
#include <list>


namespace gdk
{



enum ETaskState
{
	TASK_INVALID,
	TASK_SLEEP,
	TASK_ACTIVE,
};



class GDK_CORE_EXPORT System : virtual public Unknown
{
	DECLARE_CLASS_HANDLE(System)

public:
	typedef System::Handle	System_Handle;


public:
	class GDK_CORE_EXPORT Task : virtual public Unknown
	{
		DECLARE_CLASS_HANDLE(Task)

	public:
		typedef Task::Handle	Task_Handle;

	public:
		class TaskStatus : virtual public Unknown
		{
			DECLARE_CLASS_HANDLE(TaskStatus)
			DECLARE_CLASS_INSTANCE(TaskStatus)

		public:
			System_Handle	_hSystem;
			Task_Handle		_hTask;
			ETaskState		_taskState;
			uint32_t		_timeSinceLastTick;

			//for sleep (microsecond)
			uint32_t		_sleepTime;
		};

	private:
		TaskStatus*			_taskStatus;

		//for tick (microsecond)
		uint32_t			_tickTime;


	protected:
		__INLINE__ Task(void)
			: _taskStatus(0)
			, _tickTime(0)
		{}

		__INLINE__ virtual ~Task(void)
		{
			stop();
		}


	public:
		ETaskState getTaskState(void) const;
		System*    getSystem(void) const;

		__INLINE__ void setTickTime(uint32_t t) { _tickTime = t; }

	public:
		virtual bool start(System *pSystem);
		virtual void stop(void);
		virtual bool sleep(uint32_t t);
		virtual bool waken(void);

	public:
		__INLINE__ virtual bool init(void) { return true; }
		__INLINE__ virtual void exit(void) {}
		__INLINE__ virtual void onTick(uint32_t /*timeSinceLastTick*/) {}


	private:
		friend class System;
	};


protected:
	typedef Task::TaskStatus::Handle		TaskStatus_Handle;
	typedef std::list<TaskStatus_Handle>	TaskList;

public:
	enum EState
	{
		INVALID,
		LOAD,
		INITIALIZING,
		READIED,
		RUNNING,
		SHUTTINGDOWN,
	};

private:
	int32_t			_state;
	bool			_firstTick;
	uint32_t		_beginTime;

	TaskList		_launchTasks;
	TaskList		_runingTasks;
	TaskList		_removeTasks;

	Semaphore::Handle _wakenEvent;

#if defined(_WIN32) && defined(_DEBUG)
	DWORD			_threadId;
#endif


protected:
	System(void);
	virtual ~System(void);

public:
	bool load(void);
	void unload(void);
	void start(void);

	__INLINE__ void sleep(uint32_t timeOut = -1) { _wakenEvent->wait(timeOut, true); }
	__INLINE__ void waken(void) { _wakenEvent->signal(); }
	__INLINE__ Semaphore* getSemaphore(void) const { return _wakenEvent; }
	__INLINE__ EState getState(void) const { return (EState)_state; }

public:
	virtual bool init(void);
	virtual void exit(void);
	virtual void run(void);
	virtual bool shutdown(void);
	virtual void tick(void);
	virtual void onTick(uint32_t timeSinceLastTick);

private:
	friend class Task;
};


typedef System::Task		Task;
typedef Task::TaskStatus	TaskStatus;







}//namespace gdk


#endif /*__GDK_SYSTEM_H__*/
